package com.fly.auth.user.handler

import com.fly.auth.user.pojo.UserDto
import com.fly.auth.user.service.UserService
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.reactive.awaitFirstOrNull
import kotlinx.coroutines.reactor.mono
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.*
import reactor.core.publisher.Mono

/**
 * @author  fly
 * @date  2021/5/21 14:55
 * @version 1.0
 */
@Component
class UserHandler(private val userService: UserService) {

    private val log: Logger = LoggerFactory.getLogger(UserHandler::class.java)

    suspend fun findAll(request: ServerRequest): ServerResponse = ServerResponse.ok().json()
        .bodyAndAwait(userService.findAll())

    suspend fun search(request: ServerRequest): ServerResponse = request.bodyToMono(UserDto::class.java).awaitFirstOrNull()
        ?.run {
            log.info("获取到的参数是${this.name}")
            name?.run {
                userService.findByName(this).run { ServerResponse.ok().json()
                    .bodyAndAwait(this)
                }
            } ?: kotlin.run {
                email?.run { userService.findByEmail(this).run {
                    ServerResponse.ok().json().bodyAndAwait(this)
                } } ?: ServerResponse.badRequest().json().bodyAndAwait(Mono.just("Invalid body").asFlow())
            }
        } ?: ServerResponse.badRequest().json().bodyAndAwait(Mono.just("Invalid body").asFlow())

    suspend fun addUser(request: ServerRequest): ServerResponse {

        return request.bodyToMono(UserDto::class.java).awaitFirstOrNull()
            ?.run {
                userService.addUser(this).run { ServerResponse.status(HttpStatus.CREATED).json()
                    .bodyAndAwait(this)}
            } ?: ServerResponse.badRequest().json().bodyAndAwait(flow { emit("Invalid body") })
    }

    suspend fun deleteUser(request: ServerRequest): ServerResponse = request.pathVariable("id").toLongOrNull()
        ?.run { if (userService.deleteUser(this)) ServerResponse.noContent().buildAndAwait()
        else ServerResponse.status(HttpStatus.NOT_FOUND).json().bodyAndAwait(flow { emit("source is null") })} ?: ServerResponse.badRequest().json()
        .bodyValueAndAwait(flow { emit("id must no be null") })
}